package ch.ethz.fcl.metrobuzz.render.techniques.circos.version5;

import org.lwjgl.opengl.GL11;

import ch.ethz.fcl.metrobuzz.render.techniques.circos.CircosMatrix;
import ch.ethz.fcl.metrobuzz.render.techniques.circos.Ribbon;
import ch.ethz.fcl.metrobuzz.render.techniques.circos.version2.CircosDiagram2;
import ch.ethz.fcl.metrobuzz.render.techniques.colors.MBColorTable;
import ch.ethz.fcl.metrobuzz.spatialindex.object2d.Point2D;
import ch.ethz.fcl.metrobuzz.tools.MBGL;
import ch.ethz.fcl.metrofont.MetroFont;

/**
 * 
 * @author Zeng Wei
 * @email zeng@arch.ethz.ch
 * 
 *        use glyph instead of color change to indicate ribbon direction
 */
public class CircosDiagram5 extends CircosDiagram2 {

	public CircosDiagram5(Point2D center, float radius, CircosMatrix data) {
		super(center, radius, data);
	}

	public void update() {
		super.arcElementRibbonGapRatio = 1;
		super.flyoverRingRibbonGapRatio = 1;
		super.statisticBoxInRatio = 1;
		super.statisticBoxOutRatio = 1.08f;

		super.update();
	}

	public void render(MetroFont fm) {
		if (data.getTotalSum() == 0)
			return;
		
		renderRibbon();
		renderFlyover();
		displayStatistic(fm);
	}

	protected void renderFlyover() {
		super.renderFlyover();

		GL11.glLineWidth(1.0f);
		MBColorTable.assignColor(MBColorTable.BLACK, 0.5f);
		for (int i = 1; i < data.size(); i++) {
			Point2D[] points = getEclipsePoints(outgoingStartPoints[0][i],
					outgoingEndPoints[0][i], flyoverRingRadius
							* flyoverRingOutRatio);
			MBGL.render(points, GL11.GL_LINE_STRIP);
		}
	}

	protected void renderRibbon(int i, int j) {
		if (i != j)
			if (i != 0 && j != 0) {
				Point2D[] ctrlPoints1 = {
						outgoingStartPoints[i][j],
						center.getPointAt(outgoingStartPoints[i][j],
								ribbonCtrlPtRatio),
						center.getPointAt(incomingEndPoints[i][j],
								ribbonCtrlPtRatio / arcElementRibbonGapRatio),
						incomingEndPoints[i][j] };
				Point2D[] ctrlPoints2 = {
						outgoingEndPoints[i][j],
						center.getPointAt(outgoingEndPoints[i][j],
								ribbonCtrlPtRatio),
						center.getPointAt(incomingStartPoints[i][j],
								ribbonCtrlPtRatio / arcElementRibbonGapRatio),
						incomingStartPoints[i][j] };

				Point2D outgoingMid = outgoingStartPoints[i][j].getPointAt(
						outgoingEndPoints[i][j], center, 0.5f);

				Point2D incomingMid = incomingEndPoints[i][j].getPointAt(
						incomingStartPoints[i][j], center, 0.5f);

				Point2D[] ctrlPointsMid = { outgoingMid,
						center.getPointAt(outgoingMid, ribbonCtrlPtRatio),
						center.getPointAt(incomingMid, ribbonCtrlPtRatio),
						incomingMid };

				Ribbon.renderAsGlyph(this.proj, ctrlPoints1, ctrlPoints2,
						ctrlPointsMid, null, null);
			} else {
				Point2D[] ctrlPoints1 = { outgoingStartPoints[i][j],
						incomingStartPoints[i][j] };
				Point2D[] ctrlPoints2 = { outgoingEndPoints[i][j],
						incomingEndPoints[i][j] };

				Point2D outgoingMid = outgoingStartPoints[i][j].getPointAt(
						outgoingEndPoints[i][j], center, 0.5f);
				Point2D incomingMid = incomingEndPoints[i][j].getPointAt(
						incomingStartPoints[i][j], center, 0.5f);

				Point2D[] ctrlPointsMid = { outgoingMid, incomingMid };

				Ribbon.renderAsGlyph(this.proj, ctrlPoints1, ctrlPoints2,
						ctrlPointsMid, null, null);
			}
	}

}
